
#include "zen_vap_label.h"
#include "zen_utf8.h"
#include "zen_ticker.h"

namespace Zen { namespace Vap {

	void TextureWithRender::setFontRender(std::shared_ptr<FontRender> render)
	{
		m_render = render;
		m_is_render_dirty = true;
	}

	void TextureWithRender::setImageEffect(ImageEffectFunction effect) {
		m_image_effect = effect;
		m_is_image_dirty = true;
	}

	void TextureWithRender::setUnderlineInPixels(int width)
	{
		if(width == m_underline_px) return;
		m_underline_px = width;
		m_is_render_dirty = true;
	}

	bool TextureWithRender::clearRenderDirty()
	{
		if(m_is_render_dirty)
		{
			m_is_render_dirty = false;

			if(!m_render)
			{
				m_is_texture_empty = true;
				return true;
			}

			if(m_render->width() && m_render->height())
			{
				auto set = FontRender::RenderSetting();
				set.underline = m_underline_px;
				set.fill = 0;

				m_image = m_render->renderImage(0, 0, set);
			}
			else
			{
				m_image = nullptr;
			}
			m_is_image_dirty = true;
		}
		if(m_is_image_dirty)
		{
			m_is_image_dirty = false;

			auto image = (m_image_effect? m_image_effect(m_image) : m_image);

			if(!image || image->format() == ePixel::None) {

				m_is_texture_empty = true;
			}
			else
			{
				// re create
				m_texture_rendered = Texture::Create();
				m_texture_rendered->set(image);
				m_is_texture_empty = false;
			}

			return true;
		}
		return false;
	}

	SharedTexture TextureWithRender::getTextureRendered() {
		if(m_is_texture_empty) return nullptr;
		return m_texture_rendered;
	}

/// with font
	void TextureWithFont::setFontBrush(std::shared_ptr<FontBrush> font)
	{
		if(font == m_font) return;
		m_font = font;
		m_is_font_dirty = true;
	}
	void TextureWithFont::setMaxWidthInPixels(int pixels)
	{
		if(pixels == m_max_width_px) return;
		m_max_width_px = pixels;
		m_is_font_dirty = true;
	}

	void TextureWithFont::setCharsSpacingInPixels(int pixels)
	{
		if(pixels == m_char_spacing_px) return;
		m_char_spacing_px = pixels;
		m_is_font_dirty = true;
	}

	void TextureWithFont::setLinesSpacingInPixels(int pixels)
	{
		if(pixels == m_line_spacing_px) return;
		m_line_spacing_px = pixels;
		m_is_font_dirty = true;
	}

	void TextureWithFont::setTextAlignment(float alignment)
	{
		if(alignment == m_alignment) return;
		m_alignment = alignment;
		m_is_font_dirty = true;
	}

	void TextureWithFont::setText(std::string const & text)
	{
		if(m_text == text) return;
		m_text = text;
		m_is_font_dirty = true;
	}

	bool TextureWithFont::clearFontDirty()
	{
		if(m_is_font_dirty) {

			m_is_font_dirty = false;

			auto text32 = Zen::ToU32(m_text);

			auto style = FontRender::Style();
			style.alignment = m_alignment;
			style.word_space = m_char_spacing_px;
			style.line_space = m_line_spacing_px;
			style.width_limit = m_max_width_px;

			auto render = FontRender::Create(m_font, text32, style);

			this->setFontRender(render);

			return this->clearRenderDirty();
		}
		return false;
	}
/// label
	void Label::setFontSize(float size)
	{
		if(size == m_font_size) return;
		m_font_size = size;
		m_is_font_size_dirty = true;
	}

	void Label::updateContent()
	{
		if(this->clearFontDirty())
		{
			this->setTexture(getTextureRendered());
			m_is_font_size_dirty = true;
		}
		if(m_is_font_size_dirty) {

			if(getFontBrush())
			{
				float scale = m_font_size / getFontBrush()->getHeight();
				this->setTextureScale({scale, scale});
			}
			m_is_font_size_dirty = false;
		}
		Sprite::updateContent();
	}

}}
